<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>推箱子游戏</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Arial Rounded MT Bold', 'Segoe UI', sans-serif;
            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
            color: #fff;
        }
        
        .game-container {
            max-width: 800px;
            width: 100%;
            background: rgba(0, 0, 0, 0.7);
            border-radius: 20px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            overflow: hidden;
            padding: 20px;
        }
        
        header {
            text-align: center;
            padding: 15px 0;
            margin-bottom: 20px;
            border-bottom: 2px solid #ff9800;
        }
        
        h1 {
            font-size: 2.8rem;
            color: #ff9800;
            text-shadow: 0 0 10px rgba(255, 152, 0, 0.7);
            letter-spacing: 2px;
        }
        
        .game-info {
            display: flex;
            justify-content: space-between;
            margin-bottom: 20px;
            background: rgba(255, 255, 255, 0.1);
            padding: 15px;
            border-radius: 10px;
        }
        
        .info-item {
            text-align: center;
            flex: 1;
        }
        
        .info-label {
            font-size: 1rem;
            color: #ff9800;
            margin-bottom: 5px;
        }
        
        .info-value {
            font-size: 1.8rem;
            font-weight: bold;
        }
        
        .game-board {
            display: flex;
            justify-content: center;
            margin-bottom: 25px;
        }
        
        .board {
            display: grid;
            grid-gap: 0;
            background: #333;
            border: 3px solid #555;
            border-radius: 5px;
            overflow: hidden;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
        }
        
        .cell {
            width: 50px;
            height: 50px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 30px;
            background: #444;
        }
        
        @media (max-width: 600px) {
            .cell {
                width: 40px;
                height: 40px;
                font-size: 24px;
            }
        }
        
        @media (max-width: 400px) {
            .cell {
                width: 30px;
                height: 30px;
                font-size: 18px;
            }
        }
        
        .wall {
            background: #5d4037;
            box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5);
        }
        
        .player {
            color: #2196f3;
            text-shadow: 0 0 10px #2196f3;
        }
        
        .box {
            color: #ff9800;
            text-shadow: 0 0 10px #ff9800;
        }
        
        .target {
            background: #e91e63;
            border-radius: 50%;
            width: 60%;
            height: 60%;
            box-shadow: 0 0 10px #e91e63;
        }
        
        .box-on-target {
            color: #4caf50;
            text-shadow: 0 0 10px #4caf50;
        }
        
        .player-on-target {
            color: #2196f3;
            text-shadow: 0 0 10px #2196f3;
        }
        
        .controls {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            gap: 15px;
            margin-bottom: 20px;
        }
        
        button {
            background: linear-gradient(to bottom, #ff9800, #f57c00);
            color: white;
            border: none;
            padding: 12px 25px;
            font-size: 1.1rem;
            border-radius: 50px;
            cursor: pointer;
            transition: all 0.3s;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
            font-weight: bold;
            letter-spacing: 1px;
        }
        
        button:hover {
            transform: translateY(-3px);
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
            background: linear-gradient(to bottom, #ffa726, #fb8c00);
        }
        
        button:active {
            transform: translateY(1px);
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
        }
        
        .level-selector {
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
            gap: 10px;
            margin-top: 20px;
        }
        
        .level-btn {
            padding: 8px 15px;
            font-size: 0.9rem;
        }
        
        .instructions {
            background: rgba(255, 255, 255, 0.1);
            padding: 15px;
            border-radius: 10px;
            margin-top: 20px;
        }
        
        .instructions h3 {
            color: #ff9800;
            margin-bottom: 10px;
            text-align: center;
        }
        
        .instructions p {
            line-height: 1.6;
            text-align: center;
        }
        
        .win-message {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.9);
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            z-index: 100;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.5s;
        }
        
        .win-message.show {
            opacity: 1;
            pointer-events: all;
        }
        
        .win-content {
            background: rgba(50, 50, 50, 0.95);
            padding: 40px;
            border-radius: 20px;
            text-align: center;
            max-width: 90%;
            width: 500px;
            box-shadow: 0 0 50px rgba(255, 152, 0, 0.7);
            border: 3px solid #ff9800;
        }
        
        .win-content h2 {
            font-size: 3rem;
            color: #4caf50;
            margin-bottom: 20px;
            text-shadow: 0 0 20px #4caf50;
        }
        
        .win-content p {
            font-size: 1.5rem;
            margin-bottom: 30px;
        }
        
        .directional-controls {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            grid-template-rows: repeat(3, 1fr);
            gap: 10px;
            max-width: 200px;
            margin: 20px auto;
        }
        
        .dir-btn {
            width: 60px;
            height: 60px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 1.5rem;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 10px;
            cursor: pointer;
            transition: all 0.2s;
        }
        
        .dir-btn:hover {
            background: rgba(255, 152, 0, 0.3);
        }
        
        .dir-btn:active {
            transform: scale(0.95);
        }
        
        .up { grid-column: 2; grid-row: 1; }
        .left { grid-column: 1; grid-row: 2; }
        .right { grid-column: 3; grid-row: 2; }
        .down { grid-column: 2; grid-row: 3; }
    </style>
</head>
<body>
    <div class="game-container">
        <header>
            <h1>推箱子游戏</h1>
        </header>
        
        <div class="game-info">
            <div class="info-item">
                <div class="info-label">关卡</div>
                <div class="info-value" id="level-display">1</div>
            </div>
            <div class="info-item">
                <div class="info-label">移动次数</div>
                <div class="info-value" id="moves-display">0</div>
            </div>
            <div class="info-item">
                <div class="info-label">剩余箱子</div>
                <div class="info-value" id="boxes-display">3</div>
            </div>
        </div>
        
        <div class="game-board">
            <div class="board" id="game-board"></div>
        </div>
        
        <div class="controls">
            <button id="reset-btn">重置关卡</button>
            <button id="undo-btn">撤销一步</button>
            <button id="prev-level">上一关</button>
            <button id="next-level">下一关</button>
        </div>
        
        <div class="directional-controls">
            <div class="dir-btn up" data-dir="up">↑</div>
            <div class="dir-btn left" data-dir="left">←</div>
            <div class="dir-btn right" data-dir="right">→</div>
            <div class="dir-btn down" data-dir="down">↓</div>
        </div>
        
        <div class="level-selector">
            <button class="level-btn" data-level="1">关卡 1</button>
            <button class="level-btn" data-level="2">关卡 2</button>
            <button class="level-btn" data-level="3">关卡 3</button>
            <button class="level-btn" data-level="4">关卡 4</button>
            <button class="level-btn" data-level="5">关卡 5</button>
        </div>
        
        <div class="instructions">
            <h3>游戏说明</h3>
            <p>使用键盘方向键或屏幕上的方向按钮控制角色移动。</p>
            <p>将所有箱子推到目标位置（红色圆圈）即可过关。</p>
            <p>箱子只能向前推，不能向后拉，也不能同时推动两个箱子。</p>
        </div>
    </div>
    
    <div class="win-message" id="win-message">
        <div class="win-content">
            <h2>恭喜过关！</h2>
            <p>你用了 <span id="win-moves">0</span> 步完成了本关</p>
            <button id="next-level-btn">下一关</button>
        </div>
    </div>

    <script>
        // 游戏元素常量
        const EMPTY = 0;
        const WALL = 1;
        const BOX = 2;
        const TARGET = 3;
        const PLAYER = 4;
        const BOX_ON_TARGET = 5;
        const PLAYER_ON_TARGET = 6;
        
        // 游戏关卡设计
        const levels = [
            // 关卡 1
            [
                [1, 1, 1, 1, 1, 1, 1],
                [1, 0, 0, 0, 0, 0, 1],
                [1, 0, 0, 2, 0, 0, 1],
                [1, 0, 3, 4, 3, 0, 1],
                [1, 0, 0, 2, 0, 0, 1],
                [1, 0, 0, 0, 0, 0, 1],
                [1, 1, 1, 1, 1, 1, 1]
            ],
            // 关卡 2
            [
                [1, 1, 1, 1, 1, 1, 1],
                [1, 0, 0, 0, 0, 0, 1],
                [1, 0, 2, 3, 2, 0, 1],
                [1, 0, 3, 4, 3, 0, 1],
                [1, 0, 2, 3, 2, 0, 1],
                [1, 0, 0, 0, 0, 0, 1],
                [1, 1, 1, 1, 1, 1, 1]
            ],
            // 关卡 3
            [
                [1, 1, 1, 1, 1, 1, 1, 1],
                [1, 0, 0, 0, 0, 0, 0, 1],
                [1, 0, 2, 0, 2, 3, 0, 1],
                [1, 0, 0, 1, 0, 0, 0, 1],
                [1, 0, 3, 4, 2, 0, 0, 1],
                [1, 0, 0, 0, 3, 0, 0, 1],
                [1, 0, 0, 0, 0, 0, 0, 1],
                [1, 1, 1, 1, 1, 1, 1, 1]
            ],
            // 关卡 4
            [
                [1, 1, 1, 1, 1, 1, 1, 1],
                [1, 0, 0, 0, 0, 0, 0, 1],
                [1, 0, 3, 2, 0, 3, 0, 1],
                [1, 0, 0, 1, 2, 1, 0, 1],
                [1, 0, 3, 2, 4, 0, 0, 1],
                [1, 0, 0, 0, 3, 0, 0, 1],
                [1, 0, 0, 0, 0, 0, 0, 1],
                [1, 1, 1, 1, 1, 1, 1, 1]
            ],
            // 关卡 5
            [
                [1, 1, 1, 1, 1, 1, 1, 1, 1],
                [1, 0, 0, 0, 0, 0, 0, 0, 1],
                [1, 0, 0, 0, 1, 1, 1, 0, 1],
                [1, 0, 0, 0, 2, 0, 0, 0, 1],
                [1, 0, 1, 0, 3, 0, 1, 0, 1],
                [1, 0, 0, 0, 2, 3, 0, 0, 1],
                [1, 0, 0, 4, 3, 2, 0, 0, 1],
                [1, 0, 0, 0, 0, 0, 0, 0, 1],
                [1, 1, 1, 1, 1, 1, 1, 1, 1]
            ]
        ];
        
        // 游戏状态
        let currentLevel = 0;
        let moves = 0;
        let gameState = [];
        let history = [];
        
        // DOM元素
        const gameBoard = document.getElementById('game-board');
        const movesDisplay = document.getElementById('moves-display');
        const boxesDisplay = document.getElementById('boxes-display');
        const levelDisplay = document.getElementById('level-display');
        const winMessage = document.getElementById('win-message');
        const winMoves = document.getElementById('win-moves');
        
        // 初始化游戏
        function initGame() {
            // 重置游戏状态
            moves = 0;
            history = [];
            gameState = JSON.parse(JSON.stringify(levels[currentLevel]));
            updateDisplay();
            renderBoard();
            
            // 添加键盘事件监听
            document.addEventListener('keydown', handleKeyPress);
        }
        
        // 渲染游戏板
        function renderBoard() {
            gameBoard.innerHTML = '';
            gameBoard.style.gridTemplateColumns = `repeat(${gameState[0].length}, 1fr)`;
            
            let boxesLeft = 0;
            
            for (let y = 0; y < gameState.length; y++) {
                for (let x = 0; x < gameState[y].length; x++) {
                    const cell = document.createElement('div');
                    cell.className = 'cell';
                    
                    switch (gameState[y][x]) {
                        case WALL:
                            cell.classList.add('wall');
                            cell.innerHTML = '■';
                            break;
                        case BOX:
                            cell.classList.add('box');
                            cell.innerHTML = '◼';
                            boxesLeft++;
                            break;
                        case TARGET:
                            cell.classList.add('target');
                            break;
                        case PLAYER:
                            cell.classList.add('player');
                            cell.innerHTML = '☻';
                            break;
                        case BOX_ON_TARGET:
                            cell.classList.add('box', 'box-on-target');
                            cell.innerHTML = '◼';
                            break;
                        case PLAYER_ON_TARGET:
                            cell.classList.add('player', 'player-on-target');
                            cell.innerHTML = '☻';
                            break;
                        default:
                            // 空白单元格不需要特殊处理
                            break;
                    }
                    
                    gameBoard.appendChild(cell);
                }
            }
            
            boxesDisplay.textContent = boxesLeft;
        }
        
        // 更新显示
        function updateDisplay() {
            movesDisplay.textContent = moves;
            levelDisplay.textContent = currentLevel + 1;
        }
        
        // 处理键盘输入
        function handleKeyPress(e) {
            let direction = null;
            
            switch (e.key) {
                case 'ArrowUp':
                    direction = 'up';
                    break;
                case 'ArrowDown':
                    direction = 'down';
                    break;
                case 'ArrowLeft':
                    direction = 'left';
                    break;
                case 'ArrowRight':
                    direction = 'right';
                    break;
                default:
                    return; // 忽略其他按键
            }
            
            movePlayer(direction);
        }
        
        // 移动玩家
        function movePlayer(direction) {
            // 找到玩家位置
            let playerX, playerY;
            for (let y = 0; y < gameState.length; y++) {
                for (let x = 0; x < gameState[y].length; x++) {
                    if (gameState[y][x] === PLAYER || gameState[y][x] === PLAYER_ON_TARGET) {
                        playerX = x;
                        playerY = y;
                    }
                }
            }
            
            // 计算移动方向
            let dx = 0, dy = 0;
            switch (direction) {
                case 'up': dy = -1; break;
                case 'down': dy = 1; break;
                case 'left': dx = -1; break;
                case 'right': dx = 1; break;
            }
            
            // 计算新位置
            const newX = playerX + dx;
            const newY = playerY + dy;
            
            // 检查新位置是否有效
            if (newX < 0 || newY < 0 || newY >= gameState.length || newX >= gameState[0].length) {
                return; // 超出边界
            }
            
            // 保存当前状态到历史记录
            history.push(JSON.parse(JSON.stringify(gameState)));
            if (history.length > 50) history.shift(); // 限制历史记录长度
            
            // 处理移动
            if (gameState[newY][newX] === EMPTY || gameState[newY][newX] === TARGET) {
                // 移动到空地或目标点
                movePlayerTo(playerX, playerY, newX, newY);
                moves++;
            } else if (gameState[newY][newX] === BOX || gameState[newY][newX] === BOX_ON_TARGET) {
                // 尝试推动箱子
                const boxNewX = newX + dx;
                const boxNewY = newY + dy;
                
                if (boxNewX < 0 || boxNewY < 0 || boxNewY >= gameState.length || boxNewX >= gameState[0].length) {
                    return; // 箱子超出边界
                }
                
                if (gameState[boxNewY][boxNewX] === EMPTY || gameState[boxNewY][boxNewX] === TARGET) {
                    // 可以推动箱子
                    moveBox(newX, newY, boxNewX, boxNewY);
                    movePlayerTo(playerX, playerY, newX, newY);
                    moves++;
                }
            }
            
            // 更新显示
            updateDisplay();
            renderBoard();
            
            // 检查是否获胜
            checkWin();
        }
        
        // 移动玩家到新位置
        function movePlayerTo(oldX, oldY, newX, newY) {
            // 处理旧位置
            if (gameState[oldY][oldX] === PLAYER_ON_TARGET) {
                gameState[oldY][oldX] = TARGET;
            } else {
                gameState[oldY][oldX] = EMPTY;
            }
            
            // 处理新位置
            if (gameState[newY][newX] === TARGET) {
                gameState[newY][newX] = PLAYER_ON_TARGET;
            } else {
                gameState[newY][newX] = PLAYER;
            }
        }
        
        // 移动箱子
        function moveBox(oldX, oldY, newX, newY) {
            // 处理旧位置
            if (gameState[oldY][oldX] === BOX_ON_TARGET) {
                gameState[oldY][oldX] = PLAYER; // 玩家会移动到这里，所以暂时设为PLAYER
            } else {
                gameState[oldY][oldX] = EMPTY;
            }
            
            // 处理新位置
            if (gameState[newY][newX] === TARGET) {
                gameState[newY][newX] = BOX_ON_TARGET;
            } else {
                gameState[newY][newX] = BOX;
            }
        }
        
        // 检查是否获胜
        function checkWin() {
            for (let y = 0; y < gameState.length; y++) {
                for (let x = 0; x < gameState[y].length; x++) {
                    // 如果有箱子不在目标点上，游戏继续
                    if (gameState[y][x] === BOX) {
                        return;
                    }
                }
            }
            
            // 所有箱子都在目标点上，玩家获胜
            showWinMessage();
        }
        
        // 显示获胜消息
        function showWinMessage() {
            winMoves.textContent = moves;
            winMessage.classList.add('show');
        }
        
        // 撤销上一步
        function undoMove() {
            if (history.length > 0) {
                gameState = history.pop();
                if (moves > 0) moves--;
                updateDisplay();
                renderBoard();
            }
        }
        
        // 切换到下一关
        function nextLevel() {
            if (currentLevel < levels.length - 1) {
                currentLevel++;
                winMessage.classList.remove('show');
                initGame();
            } else {
                winMessage.classList.remove('show');
                alert('恭喜你完成了所有关卡！');
                currentLevel = 0;
                initGame();
            }
        }
        
        // 切换到上一关
        function prevLevel() {
            if (currentLevel > 0) {
                currentLevel--;
                winMessage.classList.remove('show');
                initGame();
            }
        }
        
        // 重置当前关卡
        function resetLevel() {
            winMessage.classList.remove('show');
            initGame();
        }
        
        // 加载指定关卡
        function loadLevel(level) {
            currentLevel = level - 1;
            winMessage.classList.remove('show');
            initGame();
        }
        
        // 事件监听器设置
        document.getElementById('reset-btn').addEventListener('click', resetLevel);
        document.getElementById('undo-btn').addEventListener('click', undoMove);
        document.getElementById('prev-level').addEventListener('click', prevLevel);
        document.getElementById('next-level').addEventListener('click', nextLevel);
        document.getElementById('next-level-btn').addEventListener('click', nextLevel);
        
        // 关卡选择按钮
        document.querySelectorAll('.level-btn').forEach(button => {
            button.addEventListener('click', () => {
                const level = parseInt(button.getAttribute('data-level'));
                loadLevel(level);
            });
        });
        
        // 方向控制按钮
        document.querySelectorAll('.dir-btn').forEach(button => {
            button.addEventListener('click', () => {
                const direction = button.getAttribute('data-dir');
                movePlayer(direction);
            });
        });
        
        // 初始化游戏
        initGame();
    </script>
</body>
</html>